home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / dice-3.16.lha / doc / rexx.doc < prev    next >
Text File  |  1994-02-13  |  26KB  |  780 lines

  1.  
  2.                DICE AREXX SUPPORT
  3.  
  4.     XXX handle sending a command w/ multiple arguments
  5.     XXX handle custom returns of messages
  6.  
  7.     DICE maintains several routines to automatically handle most of the
  8.     grunt work involved in writing a program with AREXX support, you as
  9.     a programmer need only setup part of the event loop and the command
  10.     dispatch.  By calling DICE's ARexx support routines you automatically
  11.     cause DICE to bring in startup and exit code to maintain it.
  12.  
  13.     The first thing you need to do is declare char *RexxHostName;  You have
  14.     two choices (example).
  15.  
  16.     char *RexxHostName = "DME";
  17.     char *RexxHostName = NULL;
  18.  
  19.     The first case is the most common -- by declaring RexxHostName with a
  20.     string DICE will automatically setup its ARexx subsystem and
  21.     automatically create an application ARexx port, finding an appropriate
  22.     slot number 01 through 99 (the actual port will be named DME.nn where nn
  23.     is 01 through 99).    Note that DICE sets up its ARexx subsystem BEFORE
  24.     YOUR MAIN() IS CALLED, so the assignment to RexxHostName must be part
  25.     of the declaration.
  26.  
  27.     The second case, declaring RexxHostName to be NULL, causes DICE to
  28.     setup it's ARexx subsystem but *NOT* create any ARexx ports.  Your
  29.     main() must then create a Global ARexx port using:
  30.  
  31.     r = CreateGlobalDiceRexxPort(NULL, char *globalName);
  32.  
  33.     Passing NULL as the message port causes DICE to initialize it's
  34.     internal RexxPort structure as a global ARexx message port.
  35.  
  36.     If you do not do either of the above two steps beware that DICE's
  37.     internal RexxPort will be invalid and unusable.
  38.  
  39.     Regardless of how you initialize RexxHostName, DICE will automatically
  40.     open rexxsyslib.library for you.  DICE can handle an arbitrary number
  41.     of nesting levels and multiple ARexx ports simultaniously.    Finally,
  42.     DICE fully resource tracks all ARexx operations done through this
  43.     interface, including messages in progress, allowing ^C BREAK to be
  44.     operational at all times!    That is, DICE WILL AUTOMATICALLY CLEANUP
  45.     THE MESS THAT IS LEFT IF SOMEONE BREAK's THE PROGRAM 5 NESTING LEVELS
  46.     DEEP.
  47.  
  48.     DICE's automatic AREXX support is brought in if you reference any DICE
  49.     ARexx command such as ProcessRexxCommands() (which you need to have
  50.     for your part of the interface anyway).
  51.  
  52.     You can, at any time, create and destroy DICE supported ARexx ports.
  53.     This is done via the CreateDiceRexxPort(), CreateGlobalDiceRexxPort()
  54.     calls, and DeleteDiceRexxPort) calls.  CreateDiceRexxPort() will modify
  55.     your supplied port name with a slot number, finding a free slot number
  56.     and returning it (-1 on failure).  CreateGlobalDiceRexxPort() will
  57.     not modify your supplied port name.  If you pass NULL as the port name
  58.     for either routine DICE will create a private ARexx port instead of a
  59.     public one.
  60.  
  61.  
  62.     ------------------------------ EXAMPLE 1 -----------------------------
  63.  
  64.     This example shows how to setup a global port to redirect commands to
  65.     the proper instance of the application.
  66.  
  67.     1> dcc gtest.c -o gtest
  68.     1> run gtest
  69.     1> run gtest a
  70.     1> run gtest b
  71.     1> rx gtest.rexx
  72.  
  73.     The first instance of the program, gtest without arguments, sets up a
  74.     global port called "GTEST".  Each of the other instances of the program
  75.     setup application ports "GTEST.xx".  The rexx script sends a command
  76.     to the global port and the first gtest process then scans through all
  77.     possible application ports sending the command to them until one
  78.     returns success.
  79.  
  80.     If you run the above you will note that the 'a' and 'b' commands in
  81.     the rexx script succeeded but the 'c' command failed.  If you now run
  82.     a gtest to handle c:
  83.  
  84.     1> run gtest c
  85.  
  86.     And run the rexx script again, all will succeed.
  87.  
  88.  
  89.     #include <lib/rexx.h>
  90.     #include <clib/exec_protos.h>
  91.     #include <string.h>
  92.     #include <stdlib.h>
  93.     #include <stdio.h>
  94.     #include <dos/dos.h>
  95.  
  96.     char Buf[256];
  97.  
  98.     /*
  99.      *    This program shows off using a global port for the program verses
  100.      *    an application port.  You run the program as follows:
  101.      *
  102.      */
  103.  
  104.     char *RexxHostName = NULL;    /* no automatic start */
  105.  
  106.     char *MyCommand;        /* left NULL for global port */
  107.  
  108.     main(ac, av)
  109.     char *av[];
  110.     {
  111.  
  112.     /*
  113.      *  DICE automatically opens rexxsyslib.library for us as long
  114.      *  as we reference the base variable (via extern) and not
  115.      *  declare it.  lib/rexx.h does this for us.
  116.      *
  117.      *  However, unlike other autoinits, if DICE is unable to open
  118.      *  the library it does not abort the program, hence the following.
  119.      */
  120.  
  121.     if (RexxSysBase == NULL) {
  122.         puts("Unable to open rexxsyslib.library !");
  123.         exit(20);
  124.     }
  125.  
  126.     /*
  127.      *  We left RexxHostName = NULL because our program will create
  128.      *  either a global port or an application port and we don't know
  129.      *  which one yet.
  130.      *
  131.      *  Our call to Create[Global]DiceRexxPort(NULL, ...) will cause
  132.      *  DICE to initialize our RexxHostName properly.
  133.      */
  134.  
  135.     if (ac == 1) {    /* no arguments, create global port */
  136.         short r = CreateGlobalDiceRexxPort(NULL, "GTEST");
  137.         if (r < 0) {
  138.         puts("Unable to create global port GTEST, already exists?");
  139.         exit(20);
  140.         }
  141.         printf("Created global port for redirect to proper app\n");
  142.     } else {    /* arguments, create local app port */
  143.         short r = CreateDiceRexxPort(NULL, "GTEST");
  144.         if (r < 0) {
  145.         puts("Unable to create application port GTEST!");
  146.         exit(20);
  147.         }
  148.         printf("Created application port GTEST.%02d for '%s'\n", r, av[1]);
  149.         MyCommand = av[1];
  150.     }
  151.     {
  152.         char *ptr;
  153.         int slotNo;
  154.  
  155.         slotNo = GetDiceRexxPortSlot(NULL, &ptr);
  156.         printf("slot: %d '%s'\n", slotNo, ptr);
  157.     }
  158.  
  159.     /*
  160.      *  Our main loop executes received commands
  161.      */
  162.  
  163.     for (;;) {
  164.         long mask = Wait(SIGBREAKF_CTRL_C | (1 << RexxSigBit));
  165.  
  166.         if (mask & SIGBREAKF_CTRL_C) {
  167.         printf("Terminating %s\n", (ac == 1) ? "global" : av[1]);
  168.         exit(1);
  169.         }
  170.         if (mask & (1 << RexxSigBit))
  171.         ProcessRexxCommands(NULL);
  172.     }
  173.     }
  174.  
  175.     /*
  176.      *    Our command handler depends on MyCommand... do we attempt to
  177.      *    execute the command or do we attempt to pass it on to application
  178.      *    ports ?
  179.      */
  180.  
  181.     long
  182.     DoRexxCommand(msg, port, arg0, pres)
  183.     void *msg;            /*    RexxMsg structure if we need it     */
  184.     struct MsgPort *port;   /*    MsgPort structure if we need it     */
  185.     char *arg0;     /*    arg0                    */
  186.     char **pres;    /*    where to put our result if rc==0    */
  187.     {
  188.     int rc;
  189.  
  190.     if (MyCommand == NULL) {
  191.         short i;
  192.         char buf[32];
  193.  
  194.         printf("Global Redirect command: %s\n", arg0);
  195.  
  196.         for (i = 1; i < 100; ++i) {
  197.         sprintf(buf, "%s.%02d", RexxHostName, i);
  198.         if ((rc = PlaceRexxCommandDirect(NULL, buf, arg0, pres, NULL)) == 0)
  199.             break;
  200.         }
  201.         if (i == 100) {
  202.         printf("Global: Command failed\n");
  203.         rc = 5;
  204.         }
  205.     } else {
  206.         printf("MatchCheck %s vs %s\n", arg0, MyCommand);
  207.         if (stricmp(arg0, MyCommand) == 0) {
  208.         *pres = "success!";
  209.         rc = 0;
  210.         } else {
  211.         *pres = "failure";
  212.         rc = 5;
  213.         }
  214.     }
  215.     return(rc);
  216.     }
  217.  
  218.  
  219.  
  220.  
  221.     --------- gtest.rexx --------
  222.     /* gtest */
  223.  
  224.     OPTIONS RESULTS
  225.  
  226.     address GTEST
  227.  
  228.     RESULT = 'no result'
  229.     a
  230.     say RC ',' RESULT
  231.  
  232.     RESULT = 'no result'
  233.     b
  234.     say RC ',' RESULT
  235.  
  236.     RESULT = 'no result'
  237.     c
  238.     say RC ',' RESULT
  239.  
  240.  
  241.     ------------------------------ EXAMPLE 2 -----------------------------
  242.  
  243.     This example shows off DICE's capability to arbitrarily nest ARexx
  244.     commands.
  245.  
  246.     To test, run the program in one CLI and the rexx script in another.
  247.     Try running the rexx script without typing ^E from the test program,
  248.     then try running the rexx script after typing ^E from the test program
  249.     (to enable the second ARexx port).
  250.  
  251.     Finally, just for fun, try ^C (BREAKing) your test program while it's
  252.     in the middle of processing ARexx commands.
  253.  
  254.     1> dcc test.c -o test
  255.     1> test
  256.     ...
  257.  
  258.     2> rx xx.rexx
  259.     etc...
  260.  
  261.  
  262.  
  263.     #include <lib/rexx.h>
  264.     #include <clib/exec_protos.h>
  265.     #include <string.h>
  266.     #include <stdlib.h>
  267.     #include <stdio.h>
  268.     #include <dos/dos.h>
  269.  
  270.     char Buf[256];
  271.  
  272.     /*
  273.      *    This program shows off using two ports.  The first is created
  274.      *    automatical